<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>弹性下拉刷新</title>
		<style type="text/css">
			body, html {
  height: 100%;
  width: 100%;
  display: table;
  background-color: #F4F4F6;
}

.center {
  width: 100%;
  display: table-cell;
  vertical-align: middle;
}

.iphone {
  border: 1px solid #C0C4D7;
  width: 320px;
  max-height: 500px;
  margin: 50px auto;
  overflow: hidden;
  box-shadow: 1px 1px 0 0.2px rgba(236, 237, 242, 0.99167),2px 2px 0 0.4px rgba(236, 237, 242, 0.98333),3px 3px 0 0.6px rgba(236, 237, 242, 0.975),4px 4px 0 0.8px rgba(236, 237, 242, 0.96667),5px 5px 0 1px rgba(236, 237, 242, 0.95833),6px 6px 0 1.2px rgba(236, 237, 242, 0.95),7px 7px 0 1.4px rgba(236, 237, 242, 0.94167),8px 8px 0 1.6px rgba(236, 237, 242, 0.93333),9px 9px 0 1.8px rgba(236, 237, 242, 0.925),10px 10px 0 2px rgba(236, 237, 242, 0.91667),11px 11px 0 2.2px rgba(236, 237, 242, 0.90833),12px 12px 0 2.4px rgba(236, 237, 242, 0.9),13px 13px 0 2.6px rgba(236, 237, 242, 0.89167),14px 14px 0 2.8px rgba(236, 237, 242, 0.88333),15px 15px 0 3px rgba(236, 237, 242, 0.875),16px 16px 0 3.2px rgba(236, 237, 242, 0.86667),17px 17px 0 3.4px rgba(236, 237, 242, 0.85833),18px 18px 0 3.6px rgba(236, 237, 242, 0.85),19px 19px 0 3.8px rgba(236, 237, 242, 0.84167),20px 20px 0 4px rgba(236, 237, 242, 0.83333),21px 21px 0 4.2px rgba(236, 237, 242, 0.825),22px 22px 0 4.4px rgba(236, 237, 242, 0.81667),23px 23px 0 4.6px rgba(236, 237, 242, 0.80833),24px 24px 0 4.8px rgba(236, 237, 242, 0.8),25px 25px 0 5px rgba(236, 237, 242, 0.79167),26px 26px 0 5.2px rgba(236, 237, 242, 0.78333),27px 27px 0 5.4px rgba(236, 237, 242, 0.775),28px 28px 0 5.6px rgba(236, 237, 242, 0.76667),29px 29px 0 5.8px rgba(236, 237, 242, 0.75833),30px 30px 0 6px rgba(236, 237, 242, 0.75),31px 31px 0 6.2px rgba(236, 237, 242, 0.74167),32px 32px 0 6.4px rgba(236, 237, 242, 0.73333),33px 33px 0 6.6px rgba(236, 237, 242, 0.725),34px 34px 0 6.8px rgba(236, 237, 242, 0.71667),35px 35px 0 7px rgba(236, 237, 242, 0.70833),36px 36px 0 7.2px rgba(236, 237, 242, 0.7),37px 37px 0 7.4px rgba(236, 237, 242, 0.69167),38px 38px 0 7.6px rgba(236, 237, 242, 0.68333),39px 39px 0 7.8px rgba(236, 237, 242, 0.675),40px 40px 0 8px rgba(236, 237, 242, 0.66667),41px 41px 0 8.2px rgba(236, 237, 242, 0.65833),42px 42px 0 8.4px rgba(236, 237, 242, 0.65),43px 43px 0 8.6px rgba(236, 237, 242, 0.64167),44px 44px 0 8.8px rgba(236, 237, 242, 0.63333),45px 45px 0 9px rgba(236, 237, 242, 0.625),46px 46px 0 9.2px rgba(236, 237, 242, 0.61667),47px 47px 0 9.4px rgba(236, 237, 242, 0.60833),48px 48px 0 9.6px rgba(236, 237, 242, 0.6),49px 49px 0 9.8px rgba(236, 237, 242, 0.59167),50px 50px 0 10px rgba(236, 237, 242, 0.58333),51px 51px 0 10.2px rgba(236, 237, 242, 0.575),52px 52px 0 10.4px rgba(236, 237, 242, 0.56667),53px 53px 0 10.6px rgba(236, 237, 242, 0.55833),54px 54px 0 10.8px rgba(236, 237, 242, 0.55),55px 55px 0 11px rgba(236, 237, 242, 0.54167),56px 56px 0 11.2px rgba(236, 237, 242, 0.53333),57px 57px 0 11.4px rgba(236, 237, 242, 0.525),58px 58px 0 11.6px rgba(236, 237, 242, 0.51667),59px 59px 0 11.8px rgba(236, 237, 242, 0.50833),60px 60px 0 12px rgba(236, 237, 242, 0.5),61px 61px 0 12.2px rgba(236, 237, 242, 0.49167),62px 62px 0 12.4px rgba(236, 237, 242, 0.48333),63px 63px 0 12.6px rgba(236, 237, 242, 0.475),64px 64px 0 12.8px rgba(236, 237, 242, 0.46667),65px 65px 0 13px rgba(236, 237, 242, 0.45833),66px 66px 0 13.2px rgba(236, 237, 242, 0.45),67px 67px 0 13.4px rgba(236, 237, 242, 0.44167),68px 68px 0 13.6px rgba(236, 237, 242, 0.43333),69px 69px 0 13.8px rgba(236, 237, 242, 0.425),70px 70px 0 14px rgba(236, 237, 242, 0.41667),71px 71px 0 14.2px rgba(236, 237, 242, 0.40833),72px 72px 0 14.4px rgba(236, 237, 242, 0.4),73px 73px 0 14.6px rgba(236, 237, 242, 0.39167),74px 74px 0 14.8px rgba(236, 237, 242, 0.38333),75px 75px 0 15px rgba(236, 237, 242, 0.375),76px 76px 0 15.2px rgba(236, 237, 242, 0.36667),77px 77px 0 15.4px rgba(236, 237, 242, 0.35833),78px 78px 0 15.6px rgba(236, 237, 242, 0.35),79px 79px 0 15.8px rgba(236, 237, 242, 0.34167),80px 80px 0 16px rgba(236, 237, 242, 0.33333),81px 81px 0 16.2px rgba(236, 237, 242, 0.325),82px 82px 0 16.4px rgba(236, 237, 242, 0.31667),83px 83px 0 16.6px rgba(236, 237, 242, 0.30833),84px 84px 0 16.8px rgba(236, 237, 242, 0.3),85px 85px 0 17px rgba(236, 237, 242, 0.29167),86px 86px 0 17.2px rgba(236, 237, 242, 0.28333),87px 87px 0 17.4px rgba(236, 237, 242, 0.275),88px 88px 0 17.6px rgba(236, 237, 242, 0.26667),89px 89px 0 17.8px rgba(236, 237, 242, 0.25833),90px 90px 0 18px rgba(236, 237, 242, 0.25),91px 91px 0 18.2px rgba(236, 237, 242, 0.24167),92px 92px 0 18.4px rgba(236, 237, 242, 0.23333),93px 93px 0 18.6px rgba(236, 237, 242, 0.225),94px 94px 0 18.8px rgba(236, 237, 242, 0.21667),95px 95px 0 19px rgba(236, 237, 242, 0.20833),96px 96px 0 19.2px rgba(236, 237, 242, 0.2),97px 97px 0 19.4px rgba(236, 237, 242, 0.19167),98px 98px 0 19.6px rgba(236, 237, 242, 0.18333),99px 99px 0 19.8px rgba(236, 237, 242, 0.175),100px 100px 0 20px rgba(236, 237, 242, 0.16667),101px 101px 0 20.2px rgba(236, 237, 242, 0.15833),102px 102px 0 20.4px rgba(236, 237, 242, 0.15),103px 103px 0 20.6px rgba(236, 237, 242, 0.14167),104px 104px 0 20.8px rgba(236, 237, 242, 0.13333),105px 105px 0 21px rgba(236, 237, 242, 0.125),106px 106px 0 21.2px rgba(236, 237, 242, 0.11667),107px 107px 0 21.4px rgba(236, 237, 242, 0.10833),108px 108px 0 21.6px rgba(236, 237, 242, 0.1),109px 109px 0 21.8px rgba(236, 237, 242, 0.09167),110px 110px 0 22px rgba(236, 237, 242, 0.08333),111px 111px 0 22.2px rgba(236, 237, 242, 0.075),112px 112px 0 22.4px rgba(236, 237, 242, 0.06667),113px 113px 0 22.6px rgba(236, 237, 242, 0.05833),114px 114px 0 22.8px rgba(236, 237, 242, 0.05),115px 115px 0 23px rgba(236, 237, 242, 0.04167),116px 116px 0 23.2px rgba(236, 237, 242, 0.03333),117px 117px 0 23.4px rgba(236, 237, 242, 0.025),118px 118px 0 23.6px rgba(236, 237, 242, 0.01667),120px 120px 0 rgba(236, 237, 242, 0);
}

.iphone__upper {
  height: 50px;
  background-color: #C0C4D7;
  z-index: 2;
  position: relative;
}
.iphone__upper .speaker_yo {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
  height: 8px;
  width: 50%;
  left: 50%;
  bottom: 12px;
  -moz-transform: translate(-50%, 0);
  -ms-transform: translate(-50%, 0);
  -webkit-transform: translate(-50%, 0);
  transform: translate(-50%, 0);
  position: absolute;
  background-color: #F4F4F4;
}

.list__wrapper {
  -moz-transform: translate3d(0, -183px, 0);
  -ms-transform: translate3d(0, -183px, 0);
  -webkit-transform: translate3d(0, -183px, 0);
  transform: translate3d(0, -183px, 0);
  background-color: white;
}

.list {
  list-style-type: none;
  padding-left: 0;
  margin: 0;
  position: relative;
  cursor: -webkit-grab;
  cursor: grab;
}
.list:active {
  cursor: grabbing;
  cursor: -moz-grabbing;
  cursor: -webkit-grabbing;
}

.list__item {
  padding: 15px;
  background-color: white;
  position: relative;
}
.list__item .avatar {
  display: inline-block;
  background-color: #C0C4D7;
  border-radius: 4px;
  width: 60px;
  height: 60px;
}

.line-top,
.line-mid,
.line-bottom {
  -moz-border-radius: 8px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
  height: 8px;
  width: 50%;
  margin-left: 12px;
  position: absolute;
  background-color: #C0C4D7;
}

.line-top {
  top: 22px;
  width: 100px;
}

.line-mid {
  bottom: 40px;
}

.line-bottom {
  width: 65%;
  bottom: 26px;
}

.svg__wrapper {
  position: relative;
  z-index: 10;
  background-color: #8B90B1;
  cursor: -webkit-grab;
  cursor: grab;
}
.svg__wrapper:active {
  cursor: grabbing;
  cursor: -moz-grabbing;
  cursor: -webkit-grabbing;
}
.svg__wrapper svg:first-child {
  -moz-transform: translate3d(0, 93px, 0);
  -ms-transform: translate3d(0, 93px, 0);
  -webkit-transform: translate3d(0, 93px, 0);
  transform: translate3d(0, 93px, 0);
}
.svg__wrapper svg:nth-child(2) {
  position: absolute;
  top: 93px;
  left: 116px;
}
.svg__wrapper svg #progress {
  stroke-dashoffset: 345.6;
  stroke-dasharray: 345.6;
}
.svg__wrapper .border {
  position: absolute;
  top: 100%;
  width: 100%;
  height: 20px;
  background-color: #fff;
}

		</style>
	</head>
	<body>
		
<div class="center">

  <div class="iphone">

    <div class="iphone__upper">
      <span class="speaker_yo"></span>
    </div>

    <div class="list__wrapper">
      <!-- SVG -->
      <div class="svg__wrapper">

        <svg width="322" height="180" viewBox="0 0 320 180" xmlns="http://www.w3.org/2000/svg" version="1.1">
          <defs>
            <filter id="goo">
              <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
              <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7" result="goo" />
              <feBlend in="SourceGraphic" in2="goo" />
            </filter>
            <filter id="fgoo">
              <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
              <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo" />
              <feComposite in="SourceGraphic" in2="goo" operator="atop" />
            </filter>
          </defs>
          <g id="gooey-group">
            <path id="curve" d="M0 90 Q 161 90 322 90" fill="white"></path>
          </g>

          <g id="circle_group">
            <circle id="circle" cx="160" cy="190" r="20" fill="rgba(255,255,255,0)"></circle>
          </g>
          <!-- <path id="bottom-line" d="M0,120 L320,120 L320,90 L0,90" fill="white" stroke="white"></path> -->
        </svg>

        <svg width="90" height="90" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
          <path id="progress" d="M45,100a55,55 0 1,0 110,0a55,55 0 1,0 -110,0" fill="transparent" stroke="white" stroke-width="8"></path>
        </svg>


      </div>

      <!--  -->
      <ul class="list">
        <li class="list__item">
          <span class="avatar"></span>
          <span class="line-top"></span>
          <span class="line-mid"></span>
          <span class="line-bottom"></span>
        </li>
        <li class="list__item">
          <span class="avatar"></span>
          <span class="line-top"></span>
          <span class="line-mid"></span>
          <span class="line-bottom"></span>
        </li>
        <li class="list__item">
          <span class="avatar"></span>
          <span class="line-top"></span>
          <span class="line-mid"></span>
          <span class="line-bottom"></span>
        </li>
        <li class="list__item">
          <span class="avatar"></span>
          <span class="line-top"></span>
          <span class="line-mid"></span>
          <span class="line-bottom"></span>
        </li>
        <li class="list__item">
          <span class="avatar"></span>
          <span class="line-top"></span>
          <span class="line-mid"></span>
          <span class="line-bottom"></span>
        </li>
      </ul>
    </div>


  </div>


</div>
<script src="../js/jquery-1.11.2.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script type="text/javascript">
	/*
  Quick sunday afternoon remake of Ramotion's pull to refresh concept. Works on  mobile too.
  https://dribbble.com/shots/1797373-Pull-Down-To-Refresh
*/

$(document).ready(function() {

  var START = undefined,
    LIMIT = 100,

    LIST = $('.list__wrapper'),
    CURVE = $('#curve'),
    CIRCLE = $('#circle'),
    FRICTION = 1,
    FPS = 35,
    DIFFERENCE,
    ANIMATING,
    TRANSLATE_HEIGHT = 90,
    REACHED_END = false,
    CURVE_HEIGHT = 190,
    START_CURVE = 'M-10 90 Q 161 90 332 90',
    END_CURVE = 'M-10 90 Q 161 120 332 90';

  $(".list__wrapper").on('touchstart mousedown', function(event) {
    event.stopPropagation();
    event.preventDefault();
    START = event.clientY || event.originalEvent.touches[0].clientY || event.originalEvent.changedTouches[0].clientY;

    $(window).on('touchmove mousemove', function(event) {
      event.stopPropagation();
      event.preventDefault();

      if (ANIMATING) {
        return false;
      }
      if (event.type === 'touchmove') {
        var touch = event.originalEvent.touches[0] || event.originalEvent.changedTouches[0];
        DIFFERENCE = (START - touch.clientY) * (-1);

      } else {
        DIFFERENCE = (START - event.clientY) * (-1);
      }

      if (DIFFERENCE < TRANSLATE_HEIGHT) {
        translateSVG(DIFFERENCE);
        setOpacity(DIFFERENCE);
        REACHED_END = false;

      } else if (DIFFERENCE > TRANSLATE_HEIGHT && DIFFERENCE < CURVE_HEIGHT) {
        outerCurve(DIFFERENCE);
        setOpacity(DIFFERENCE);
        REACHED_END = false;
      } else if (DIFFERENCE >= CURVE_HEIGHT) {
        REACHED_END = true;
      }
    });
  });

  $(window).on('touchend mouseup', function(event) {
    event.stopPropagation();
    event.preventDefault();
    START = 0;
    if (REACHED_END) {
      runAnimation();
    } else {
      backToStart();
    }
    $(window).off('mousemove');
  });

  function backToStart() {
    if (DIFFERENCE > TRANSLATE_HEIGHT) {
      setTimeout(function() {
        $({
          x: parseInt($('.list__wrapper').css('transform').split(',')[5])
        }).animate({
          x: -183
        }, {
          duration: 300,
          step: function(now) {
            $('.list__wrapper').css({
              transform: 'translate3d(0,' + now + 'px,0)'
            })
          }
        });
      }, 100);
      $('.list').velocity({
        opacity: 1,
        duration: 300,
        delay: 200
      });
      $("#curve").velocity({
        tween: [90, DIFFERENCE]
      }, {
        duration: 150,
        loop: false,
        /*easing: [ 300, 8 ],*/
        easing: 'easeOutCubic',
        progress: function(e, c, r, s, t) {
          if (t > 90) {
            $('#curve').attr('fill', '#8B90B1');
          } else {
            $('#curve').attr('fill', 'white');
          }
          createCurve(t);
        }
      });
    } else {
      $({
        x: parseInt($('.list__wrapper').css('transform').split(',')[5])
      }).animate({
        x: -183
      }, {
        duration: 300,
        step: function(now) {
          $('.list__wrapper').css({
            transform: 'translate3d(0,' + now + 'px,0)'
          })
        }
      });
      $('.list').velocity({
        opacity: 1,
        duration: 300,
        delay: 200
      });
    }
  }

  function translateSVG(offset) {
    var dist = offset - 183;
    if (dist > -188) {
      $(LIST).css({
        transform: 'translate3d(0,' + dist + 'px,0)'
      });
    }
  }

  function setOpacity(distance) {
    distance = 140 - distance;
    var pct = distance / 140;
    $('.list').css({
      opacity: pct
    });
  }

  function runAnimation() {
    ANIMATING = true;

    $('svg:first-child').css({
      'filter': 'url(#goo)',
      '-webkit-filter': 'url(#goo)',
      '-moz-filter': 'url(#goo)',
      '-o-filter': 'url(#goo)',
      '-ms-filter': 'url(#goo)'
    });
    $("#curve").velocity({
      tween: [90, 200]
    }, {
      duration: 700,
      loop: false,
      easing: [0, 3, .3, 0.4],
      progress: function(e, c, r, s, t) {
        if (t > 90) {
          $('#curve').attr('fill', '#8B90B1');
        } else {
          $('#curve').attr('fill', 'white');
        }
        createCurve(t);
      }
    });
    setTimeout(function() {
      $('#circle_group').attr({
        'cy': 110
      });
      $('#circle').attr({
        fill: 'rgba(255,255,255,1)'
      });
      $('#circle').velocity({
        cy: 45
      }, {
        duration: 200,
        easing: 'easeOutSine'
      });

      $('#progress').velocity({
        strokeDashoffset: 0
      }, {
        duration: 800,
        delay: 300
      });
      $('svg:nth-child(2)').velocity({
        scale: 1.15,
        opacity: 0,
      }, {
        duration: 400,
        delay: 1200,
        easing: [.11, 1, .34, .98]
      });
      setTimeout(function() {
        $('#curve').attr('d', END_CURVE);
      }, 1450);
      setTimeout(function() {
        $('svg:first-child').css({
          'filter': 'none',
          '-webkit-filter': 'none',
          '-moz-filter': 'none',
          '-o-filter': 'none',
          '-ms-filter': 'none'
        });
      }, 1800);
      $('#circle').velocity({
        cy: 140
      }, {
        duration: 450,
        delay: 1300,
        complete: function() {
          $('#curve').attr('d', START_CURVE);
          $({
            x: parseInt($('.list__wrapper').css('transform').split(',')[5])
          }).animate({
            x: -183
          }, {
            step: function(now) {
              $('.list__wrapper').css({
                transform: 'translate3d(0,' + now + 'px,0)'
              })
            }
          });
          $('.list').velocity({
            opacity: 1
          }, 500);
          $('#circle').attr('cy', 190);
          $('#progress').css({
            strokeDashoffset: 345.6
          });
          $('svg:nth-child(2)').velocity({
            scale: 1,
            opacity: 1
          }, 0)
          REACHED_END = false;
          ANIMATING = false;
        }
      })
    }, 50);

  };

  function outerCurve(height) {
    var FRICTION_HEIGHT = height * FRICTION;
    var d = "M0 90 Q 161 " + FRICTION_HEIGHT + " 322 90"
    $(CURVE).attr({
      d: d,
      fill: '#8B90B1'
    });
  }

  function createCurve(height) {
    var FRICTION_HEIGHT = height * FRICTION;
    var d = "M-10 90 Q 161 " + FRICTION_HEIGHT + " 332 90"
    $(CURVE).attr('d', d);
  }
});
</script>
	</body>
</html>
